function [ blocks, ...
           blocksInfo ] = WiSiL_Encoder_blockSegmentation( bitsTx, ...
                                                           encoder )
% WISIL_ENCODER_BLOCKSEGMENTION Segment a bit stream into code blocks.
%
%  [ BLOCKS, BLOCKSINFO ] = WiSiL_Encoder_blockSegmentation( BITSTX, 
%   ENCODER ) implements the Code Block Segmentation according to the 
%  specifications in 3GPP 36.212 (V8.3.0). The input bits BITSTX are
%  segmented into code blocks BLOCKS according to the rules set in the
%  encoder parameters ENCODER. The structure of the output code blocks is
%  described in BLOCKSINFO.
%  If the input bit sequence is
%  larger than the maximum code block size defined in the specs, code block
%  segmentation is performed and at the end of each block a CRC bit
%  sequence is attached. The size of the code blocks shall follow the
%  pattern defined in 36.212, and must be one of the values shown in
%  Table 5.1.3-3 thereof. At the output of the code block segmentation only
%  two Code Blocks sizes must appear, and they must be consecutive values
%  at Table 5.1.3-3. Filler bits can be attached to the output bit
%  sequence, at the beginning of the first code block theu are always 
%  necessary. These bits are set to have null value.

% History
% ???,????
%   created
% Andre Noll Barreto, 11/Mar/2011
%   CRC overhead only, actual CRC removed


maxSize = encoder.maxBlockSize; %Maximum Code Block Size allowed.

% Load the parameters of Code Block Segmentation (Table 5.1.3-3 at 36.212):
WiSiL_Encoder_interleaverTable;

%Pre-allocating memory:
auxiliar = cell(2,1); %auxiliar variable.
blocks = cell(2,1); % output

B = length(bitsTx); % Size of input bit Sequence

if B <= maxSize
    %If B < MaxSize Code Block Sementation is not performed.
    L=0;
    numBlocks=1;
    Bout=B;
    C1 = 1;
    C2 = 0;
    K2 = 0;
else
    %If B > MaxSize Code Block is performed and a CRC bit sequence is
    %attached to the end of each block.
    L=24; %  Length of CRC bit sequence
    numBlocks=ceil(B/(maxSize-L));  %Calculating the number of blocks.
    Bout=B+numBlocks*L; %Total bits at the output of the module.
end

%Searching the size of the larger blocks. The first value of K at table 5.1.3-3
%that is larger than Bout/numBlocks
K1 = K(find( K >= Bout/numBlocks,1,'first'));


    
if (numBlocks > 1)
    %If numBlocks>1, It is necessary calculate the number of Blocks of each
    %size.
    K2 = K(find(K<K1,1,'last')); %Size of the smaller blocks. The last K at
    %table 5.1.3-3 that is smaller than K1.
    delta = K1-K2;
    C2 = floor((numBlocks*K1-Bout)/delta); %Number of blocks of smaller size.
    C1=numBlocks-C2; %Number of blocks of larger size.
    
end

% Adding filler bits, if necessary:
fillerBits = C1*K1 + C2*K2 - Bout;
aux(1:fillerBits) =  NaN;
bits = [aux bitsTx];
%--

%Sharing the input bit sequence into blocks, without CRC attachment.
auxiliar{1,1} = reshape(bits (1:C2*K2 - L * C2) ,K2-L, [] )' ;
auxiliar{2,1} = reshape(bits (C2*K2 - L * C2 +1:end), K1-L,[] )' ;
%--

%Applying the CRC attachment of each Code Block.
if numBlocks>1
    for k=1:C2
        blocks{1,1}(k,:) = [ auxiliar{1,1}(k,:), ...
                             randi([0,1],1,encoder.crc.sizeInBits) ];
    end

    for k=1:C1
        blocks{2,1}(k,:) = [ auxiliar{2,1}(k,:), ...
                             randi([0,1],1,encoder.crc.sizeInBits) ];
    end
else
    blocks{1,1}(1,:) = bits;
end
%---

blocksInfo.numBlocks = numBlocks;
blocksInfo.C1 = C1;
blocksInfo.C2 = C2;
blocksInfo.K1 = K1;
blocksInfo.K2 = K2;
blocksInfo.fillerBits = fillerBits;
